//
//  "$Id: VideoEnc.h 101448 2013-02-18 08:25:03Z hao_shiming $"
//
//  Copyright (c)1992-2007, ZheJiang Dahua Technology Stock CO.LTD.
//  All Rights Reserved.
//
//	Description:	
//	Revisions:		Year-Month-Day  SVN-Author  Modification
//

#ifndef __VIDEO_ENC_API_H__
#define __VIDEO_ENC_API_H__

#include "Types.h"
#include "VideoIn.h"
#include "VideoAnalyse.h"

#ifdef __cplusplus
extern "C" {
#endif

/// \defgroup VideoEncAPI API Video Encoder
/// 视频编码接口，可以实现一个视频输入通道多码流编码，画中画编码，多画面编码等等。
///	\n 调用流程图:
/// \code
///    ============================================
///                   |                            
///           createVideoEncoder                      
///                   |
///                 addRef
///                   |                            
///              getChipCaps
///                   |
///                getCaps
///                   |
///               setFormat                     	
///                   |
///                 start
///                   |
///         +---------|----------------+
///         |     getPacket            |
///         |    releasePacket     forceIFrame
///         |         |                |
///         +---------|----------------+
///                 stop
///                   |         
///                release                       
///                   |                            
///    ============================================
/// \endcode
/// @{


/// 视频编码压缩格式类型
typedef enum VideoEncType
{
	videoEncMPEG2 = 0,	///< MPEG2
	videoEncMPEG4,		///< MPEG4
	videoEncH263,		///< H.263
	videoEncH264,		///< H.264
	videoEncMotionJPEG,	///< MJPG
	videoEncAVS, 		///< AVS
	videoEncH265, 		///< H.265
	videoEncH264_Improve,///< H.264+
	videoEncH265_Improve,///< H.265+
	videoYuv420,
	videoEncNumber,		///< 压缩类型数目
} VideoEncType;

/// H.264编码Profile
typedef enum VideoEncH264Profile
{
	h264ProfileBaseline = 0,	///< Baseline Profile(BP)
	h264ProfileMain,			///< Main Profile(MP)
	h264ProfileExtended,		///< Extended Profile(XP)
	h264ProfileHigh,			///< High Profile(HP)
	h264ProfileNumber			///< Profile个数
}VideoEncH264Profile;

/// 编码芯片编码能力结构，128字节
typedef struct VideoEncChipCaps 
{
	ulong ladenBitrate;		///< 编码芯片支持的最高视频负载码流kbps(压缩前,按16bpp计算)
	int reserved[31];		///< 保留字节
} VideoEncChipCaps;

/// OSD叠加支持的颜色掩码
typedef enum VideoEncOSDType
{
	OSDColoreSingleBit	= 0,	///< 单色位图
	OSDASCIIString,				///< ASCII带0结束符的字符串
	OSDColoreRGB1555,			///< RGB1555位图
	OSDColoreRGB565				///< RGB565位图
} VideoEncOSDType;

/// 编码设备能力结构，128字节
typedef struct VideoEncCaps
{
	ulong types;			///< 编码芯片支持的视频压缩类型VideoEncType的掩码
	char coverCount;		///< 支持最多的区域覆盖个数。
	char titleCount;		///< 支持最多的标题叠加的个数。
	char snapByOtherSize;	///< 是否有独立的抓图分辨率，否则使用主码流分辨率。
	char coverRemain;		///< 最小不可覆盖区域面积百分比, 0~100
	float snapFps;			///< 最大抓图帧率
	uchar roiCount;			///< 最大ROI个数
	uchar h264ProfileMask; ///< H264编码Profile能力掩码
	uchar roiBackgroundFpsEnable; ///< 0:不支持非ROI区域FPS设置；1:支持非ROI区域FPS设置
	uchar maxGop;			///< 最大I帧间隔
	uchar svcTypeMask;		///< 编码芯片支持的SVC类型VideoSvcType的掩码
    uchar snapScaleEnalbe;	///< 0: 不支持抓图缩略图 1: 支持抓图缩略图
    uchar dynamicEnalbe;	///< 0: 不支持编码动态设置； 1: 支持编码动态设置
    uchar reserved1[1];		///保留
	int titleMask;			///< 支持OSD叠加类型VideoEncOSDType的掩码
	int	refModeMask;		///< 跳帧模式VideoEncRefMode支持的类型掩码
	int reserved[25];		///< 保留字节
} VideoEncCaps;


/// 视频编码码流控制模式类型
typedef enum VideoEncBitrateCtrl
{
	videoEncBitrateCtrlConstant = 0,	///< 固定码流。
	videoEncBitrateCtrlVariable,	///< 可变码流。
} VideoEncBitrateCtrl;

/// 视频帧打包格式
typedef enum VideoEncPackType
{
	videoEncPackTypeZLAV = 0,	///< ZLAV格式打包
	videoEncPackTypePS,			///< PS流格式打包
	videoEncPackTypeRAW,		///< 裸码流，不打包
	videoEncPackTypeDHAV,		///< DHAV格式打包
}VideoEncPackType;

/// 视频编码画质优化窗口信息，32字节
typedef struct VideoEncROIWindow
{
	Rect			regions;		///< 优化区域，采用绝对坐标，分辨率修改后需要重新设置参数
	uchar			quality;		///< 图像质量,取值1-6，值越大，图像质量越好,只有在可变码流下才起作用。
	uchar			reserved1[15];
}VideoEncROIWindow;

/// 视频编码画质优化，32字节
typedef struct VideoEncROI
{
	uint		count;				///< 优化区域个数
	Rect		*regions;			///< 优化区域，采用绝对坐标，分辨率修改后需要重新设置参数, 为NULL时用win字段代替
	uchar		quality;			///< 图像质量,取值1-6，值越大，图像质量越好,只有在可变码流下才起作用。
	VideoEncROIWindow *win;			///< 优化窗口信息
	uchar		backgroundFps;		///< 非ROI区域的背景帧率等级设置, 0：高，1：一般，2：差
	uchar		reserved[18];		///< 保留字节	
}VideoEncROI;

/// 视频编码Blank信息结构体，128字节
typedef struct VideoEncBlank
{
	Color				bgColor;			///< 背景颜色
	uchar				blankHeight;		///< Blank高度
	uchar				blankPostion;		///< Blank位置 0-顶部, 1-底部
	uchar				reserved1[2];
	int					reserved[30];
}VideoEncBlank;

/// 视频编码压缩格式类型
typedef enum VideoSvcType
{
	videoSvcInvalid = 0,///< SVC不使能
	videoSvcTime = 1,	///< 时域分级编码模式
	videoSvcSpace = 2,	///< 空域分级编码模式
	videoSvcNumber,		///< 压缩类型数目
} VideoSvcType;

/// 视频编码跳帧模式
typedef enum VideoEncRefMode
{
	videoNoRefMode			= 0,			///<  非跳帧模式
	videoNomalRefMode		= 1<<0,			///<  普通模式
	videoAdvanceRefMode		= 1<<1,			///<  高级模式
}VideoEncRefMode;

/// 视频编码普通跳帧模式参数
typedef struct VideoEncRefNomalModeOpt
{
	unsigned int refFrame;				///<  跳帧数	
}VideoEncRefNomalModeOpt;

/// 视频编码跳帧属性,,h264和h265编码类型支持 128字节
typedef struct VideoEncRefOptions
{
	VideoEncRefMode				mode;					///< 跳帧模式
	int							resercved[7];			///< 保留位
	union
	{
		VideoEncRefNomalModeOpt		nomalModeOpt; 
		int							resercved[24];		///< 保留位
	} options;
}VideoEncRefOptions;

/// 视频编码数据格式结构，128字节
typedef struct VideoEncFormat
{
	VideoEncType		type;				///< 压缩标准，取VideoEncType类型的值。
	uint				width;				///< 图像像素宽度，16的倍数,大于64 
	uint				height;				///< 图像像素高度，16的倍数,大于64 
	VideoEncBitrateCtrl	bitrateControl;		///< 码流控制模式，取VideoEncBitrateCtrl类型的值。 
	uint				bitrate;			///< 参考码流大小，kbps为单位。
	float				fps;				///< 帧率值，NTSC/PAL不区分
	uint				gop : 8;			///< I帧间隔，即多少帧出现一个I帧，比如PAL制下一般取值25，50等
	uint				quality : 7;		///< 图像质量，取值1-6，值越大，图像质量越好,只有在可变码流下才起作用。
	uint				qualityType : 1;	///< 图像质量取值类型，0-表示取值 1~6，1-表示取值 1~100
	VideoEncPackType	pack : 8;			///< 打包格式
	int					profile : 8;		///< 编码Profile，不同编码类型意义不同，如H.264的Profile取VideoEncH264Profile的值
	uint				size;				///< 编码后文件大小(bytes)，只支持图片码流，在固定码流下才起作用
	uchar				blankCount;			///< blank个数
	uchar				snapScaleEnalbe;    ///< 0: 不使能抓图缩略图 1: 使能抓图缩略图 
	uchar				reserved1[2];		///< 保留
	VideoEncBlank*		blank;				///< blank信息
	float				maxFps;				///< 最大帧率值，由应用给出，底层编码模块参考使用，允许填0
	VideoSvcType		svcType;			///< svc编码类型
	uint				scaleWidth;			///< 图像像素宽度
	uint				scaleHeight;	 	///< 图像像素高度
	VideoEncRefOptions	*refOptions;		///< 跳帧属性设置
	int					reserved[17];		///< 保留字节
} VideoEncFormat;


/// 帧类型
typedef enum VideoEncFrameType
{
	videoEncFrameI = 0,			///< 是I帧
	videoEncFrameP,				///< 是P帧
	videoEncFrameB,				///< 是B帧
	videoEncFrameW,				///< 是水印帧
	videoEncFrameG,				///< GPS帧
	videoEncFrameJ,				///< JPEG图像帧
	videoEncFrameSP,			///< SP帧
	videoEncFrameSI,			///< SI帧
	videoEncFrameMetadata,		///< 元数据帧
	videoEncFrameAnalyse,		///< 智能分析帧
	videoEncFrameF,				///< 人脸图像帧
	videoEncFrameBasePRef,		///< base层P帧，被enhance层P帧参考
	videoEncFrameEnhancePRef,	///< enhance层P帧，被enhance层的其它P帧参考
	videoEncFrameEnhancePNoRef, ///< enhance层P帧，不参考其它P帧 
	videoEncFrameRefIdr,		///< base层P帧，被base层P帧参考并且参考I帧，虚拟I帧
	videoEncFrameNumber			///< 帧类型数目
} VideoEncFrameType;

typedef enum SnapShotMode
{
	snapShotModeNone = 0x00000000,			///关闭抓图模式，暂时不定义具体的意义
	snapShotModeContinually = 0x00000001,	///连接抓图模式，这种情况下表示应用主动开启编码抓图，编码会给出普通抓图，编码的抓图队列中只有普通图片，默认情况下使用这种模式
	snapShotModeTrigger = 0x00000002,		///触发抓图模式，这种情况下表示应用开启编码抓图，但编码只给出触发抓图，编码的抓图队列中只有编码认为需要给出的图片（如智能人脸图），并在图片包中包含特殊标志
} SnapShotMode;

/// 视频编码缓冲结构体
typedef struct VideoEncBuf
{
	uchar	*buffer;				///< 数据缓冲指针
	int		len;					///< 数据长度
} VideoEncBuf;
/// 视频编码包，128字节
typedef struct VideoEncPacket
{
	VideoEncBuf			*vBuffer;	///< 数据缓冲数组，存储多个缓存地址，应用需依次读取
	ulong				length;		///< 数据缓冲有效长度
	uint64				pts;		///< 时间戳(jiffies_64*(1000/HZ))，毫秒为单位
	ulong				sequence;	///< 帧序号，用于校验是否丢帧
	VideoEncFrameType	type;		///< 帧类型
	char				head;		///< 是否包含帧头，1-包含，0-不包含
	char				tail;		///< 是否包含帧尾，1-包含，0-不包含
	char				newFormat;	///< 编码格式是否发生了变动，0：未变动，1：分辨率有变动，2：其他参数有变动
	char				remain;		///< 除了这个数据包，是否还有本帧或其他帧的后续数据可以获取
	ulong				utc;		///< 帧内图像对应的UTC(1970-1-1 00:00:00)秒数
	uchar				mark;		///< 指定帧标记，即从VideoIn处设置的值，0表示没有标记
	uchar				specLength;	///< 包含的CodecSpecInfo数据长度，如果为0则表示无效
	ushort				utcms;		///< UTC时间对应的毫秒数
	uchar				*specBuffer;///< CodecSpecInfo具体信息，比如H.264的PPS,SPS等信息
	uint64				ptsBeforeEnc;///< 编码前的时间戳(jiffies_64*(1000/HZ))
	uint64				ptsAfterEnc;///< 编码后的时间戳(jiffies_64*(1000/HZ))
	uint64				ptsLib;		///< 编码库从驱动取到本数据包的时间戳(jiffies_64*(1000/HZ))
	ushort				width;		///< 该帧编码数据的宽度
	ushort				height;		///< 该帧编码数据的长度
	uchar				packType;	///< 该数据包的封装格式 取VideoEncPackType的枚举值
	uchar				vSize;		///< 数据缓冲数组大小，
	uchar				res1[2];	///< 保留
	uint				flag;		///< 编码数据特殊标识信息，车牌抠图的时候是车牌的ID，0表示大图，其它表示小图。其它模式暂无定义
	VideoEncBuf			*scaleBuffer;   ////< 动检缩略图缓存
	uchar				scaleSize;		///< 动检缩略图数据缓冲数组大小，无缩略图时为0
	uchar				res2[3];		///< 保留
	int                 encType;
	int					reserved[10];///< 保留字节
} VideoEncPacket;

/// 视频编码源数据包，128字节
typedef struct VideoEncSourcePacket
{
	void				*source;		///< 视频源地址
	uint				sequence;		///< 视频源帧标记
	uchar				encode;			///< 是否编码，0:不编码，1:编码
	char				reserved1[3];	///< 保留
	int					resercved[29];	///< 保留
}VideoEncSourcePacket;

/// 视频水印，128字节
typedef struct VideoWaterMark
{
	char		index;		///< 水印序号，暂时无效
	char		enable;		///< 是否显示。0-不显示，其他参数忽略，1-显示。
	uchar *		data;		///< 水印数据，最多256字节
	int			datalen;	///< 水印数据的长度
	uchar *		key;		///< 水印密钥
	int			keylen;		///< 水印密钥的长度
	int			reserved[27];///< 保留字节
} VideoWaterMark;

/// 视频内嵌GPS，128字节
typedef struct VideoGPS
{
	ulong		utc;			///< GPS对应的UTC(1970-1-1 00:00:00)秒数
	int			longitude1000;	///< 经度*1000：单位为秒
	int			latitude1000;	///< 纬度*1000：单位为秒
	int			altitude1000;	///< 高度*1000：单位为米
	int			speed1000;		///< 速度*1000：单位为km/H
	int			bearing1000;	///< 方向角*1000：单位为°
	int			reserved[26];	///< 保留字节
} VideoGPS;

/// 帧额外信息，128字节
typedef struct VideoInExtraInfo
{
	void		*source;			///< 编码视频源地址
	ulong		sequence;			///< 帧序号.视频源地址会循环，使用sequence避免由于应用延时导致帧额外信息错误填充的情况
	int			offset;				///< 帧额外信息的存放位置，相对于编码后帧起始位置的偏移地址
	void		*buffer;			///< 帧额外信息缓冲地址
	int			length;				///< 帧额外信息长度
	int			placeholder;	///< 鱼眼图像安装方式；1顶装，2壁装；3地装
	int			reserved[26];		///< 保留字节
}VideoInExtraInfo;

/// 视频编码局部信息，128字节
typedef struct VideoEncPart
{
	Rect		region;			///< 视频局部编码坐标信息，采用绝对坐标，分辨率修改后需要重新设置参数
	uint		flag;			///< 局部区域标记，底层给编码结果时应当返回该值
	uint		source;			///< 同步模式下，yuv数据的指针，不能直接访问，异步模式可以不设置
	uint		reserved[26];	///< 保留字节
}VideoEncPart;


/// 编码配置属性，32字节
typedef struct VideoEncOptions
{
	int				width;					///< 分辨率宽
	int				height;					///< 分辨率宽	
	float			fps;					///< 帧率
	int				reserved2[28];			///< 保留值
} VideoEncOptions;


/// 前端采集配置属性，32字节
typedef struct VideoEncVinOptions
{
	VideoStandard	standard;				///< 视频制式
	uchar			wideDynamic;			///< 真实宽动态状态，0-不开启，1-开启真实宽动态，2-自动调节	
	uchar			reserved1[3];			///< 保留值
	int				width;					///< 分辨率宽
	int				height;					///< 分辨率宽
	float			fps;					///< 帧率
	int				needReboot;				///< 是否需要重启, 0-不重启，1-需要重启
	int				reserved2[25];			///< 保留值
} VideoEncVinOptions;

typedef struct VideoEncCropCfg
{
    int enable;
    Rect_ext rect;
} VideoEncCropCfg;

typedef struct VideoEncRectInfo
{
    int type;/* 0:跟踪,1:说话人跟踪 */
    Rect_ext rect;
} VideoEncRectInfo;

typedef struct VideoEncStitchCfg
{
    int num;
    int onlyRefreshSpeak;
    VideoEncRectInfo rectInfo[8];
    VideoEncRectInfo allRect;
} VideoEncStitchCfg;

/// 视频编码接口，512字节
typedef struct VideoEncoder
{
	/// 底层私有数据
	void *priv;


	/// 增加接口引用
	int (*addRef)(struct VideoEncoder *thiz);


	/// 释放接口
	int (*release)(struct VideoEncoder *thiz);


	/// 得到编码器所在的芯片ID
	///
	/// \param [in] thiz 视频编码接口指针
	/// \retval >=0 芯片ID，由库里面统一分配，不同的芯片有唯一的编号。
	///					芯片号在创建编码通道的时候得到
	/// \retval < 获取失败
	int (*getChipId)(struct VideoEncoder *thiz);


	/// 获得芯片的编码能力
	///
	/// \param [in] thiz 视频编码接口指针
	/// \param [out] caps 芯片能力结构VideoEncChipCaps指针
	///
	int (*getChipCaps)(struct VideoEncoder *thiz, VideoEncChipCaps *caps);


	/// 得到视频编码设备能力
	/// 
	/// \param [in] thiz 视频编码接口指针
	/// \retval 0 销毁失败
	/// \retval <0 销毁成功
	int (*getCaps)(struct VideoEncoder *thiz, VideoEncCaps *caps);


	/// 强制编码器产生I帧。新的I帧应该在下一个数据包VideoEncPacket第一帧。
	/// 
	/// \param [in] thiz 视频编码接口指针
	/// \retval 0  设置成功。
	/// \retval <0	设置失败。
	int (*forceIFrame)(struct VideoEncoder *thiz);


	/// 设置视频编码数据压缩的格式。
	/// 
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] format 指向视频格式结构VideoEncFormat的指针，NULL表示不编码视频。
	/// \retval 0  设置成功
	/// \retval <0	设置失败
	int (*setFormat)(struct VideoEncoder *thiz, VideoEncFormat* format);


	/// 开始编码。在视频制式、视频编码选项、图像质量、帧率、码流控制方式、分辨率、
	/// 编码模式等参数被改变时，应用程序会停止视频编码，然后重新开始视频编码。
	/// 
	/// \param [in] thiz 视频编码接口指针
	/// \retval 0  开始成功
	/// \retval <0	开始失败
	int (*start)(struct VideoEncoder *thiz);


	/// 停止编码，当前操作立即返回。
	/// 
	/// \param [in]  thiz 视频编码接口指针
	/// \retval 0  停止成功
	/// \retval <0	停止失败
	int (*stop)(struct VideoEncoder *thiz);


	/// 叠加视频编码的标题参数。
	/// 
	/// \param [in]  thiz 视频编码接口指针
	/// \param [in] title 指向标题结构VideoTitle的指针。
	/// \retval 0  设置成功
	/// \retval <0	设置失败
	int (*setTitle)(struct VideoEncoder *thiz, VideoTitle *title);


	/// 设置视频编码覆盖区域。
	/// 
	/// \param [in]  thiz 视频编码接口指针
	/// \param [in] cover 指向视频覆盖结构VideoCover的指针。
	/// \retval 0  设置成功。
	/// \retval <0	设置失败。
	int (*setCover)(struct VideoEncoder *thiz, VideoCover *cover);


	/// 读取编码数据，读为非阻塞模式；每次最多读取一帧数据，如果帧数据已经分块，
	/// 则分多次传出。如果没有数据，则返回错误。
	/// 
	/// \param [in] thiz 视频编码接口指针
	/// \param [out] packet 编码缓冲结构VideoEncPacket指针。
	/// \return>=0 通道号（在输入通道号为-1时）
	/// \retval 0  读成功
	/// \retval <0	读失败
	int (*getPacket)(struct VideoEncoder *thiz, VideoEncPacket* packet);


	/// 释放视频编码数据，需要和VideoEncGetPacket成对调用。
	///
	/// \param [in]  thiz 视频编码接口指针
	int (*releasePacket)(struct VideoEncoder *thiz);


	/// 设置视频编码中视频输入的区域。
	/// 
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] src 视频输入通道号
	/// \param rect 输入在输出中的视频区域，该区域会自动加一个边框，最后设置的区域
	///					放在视频输出的最顶层。
	/// \retval 0  设置成功
	/// \retval <0	设置失败
	int (*setInputRect)(struct VideoEncoder *thiz, int src, Rect *rect);

	
	/// 应用程序定时调用， 通知编码设备检测自身状态， 如果有错误， 重启设备，同时返回错误。 
	/// 
	/// \param [in] thiz 视频编码接口指针
	/// \retval 0  同步成功
	/// \retval <0	同步失败
	void (*synchronize)(struct VideoEncoder *thiz);


	/// 设置水印
	/// 
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] mark 指向视频水印结构VideoWaterMark的指针。
	/// \retval 0  设置成功
	/// \retval <0	设置失败
	int (*setWaterMark)(struct VideoEncoder *thiz, VideoWaterMark *mark);


	/// 设置GPS
	/// 
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] mark 指向视频GPS结构VideoGPS的指针。
	/// \retval 0  设置成功
	/// \retval <0	设置失败
	int (*setGPS)(struct VideoEncoder *thiz, VideoGPS *gps);


	/// 设置Mark匹配模式
	///
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] mode 0-标题叠加Mark匹配，1-标题叠加Mark不匹配，2-以帧序号进行匹配
	/// \retval 0  设置成功
	/// \retval <0	设置失败
	int (*setMarkMode)(struct VideoEncoder *thiz, int mode);

	/// 设置编码ROI参数
	///
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] roi 视频编码ROI参数
	/// \retval 0  设置成功
	/// \retval <0	设置失败
	int (*setROI)(struct VideoEncoder *thiz, VideoEncROI *roi);
	
	/// 设置帧额外信息，一般是对帧的描述信息，如JPEG的冗余信息
	///
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] extraInfo 帧额外信息
	/// \retval 0  设置成功
	/// \retval <0	设置失败
	int (*setExtraInfo)(struct VideoEncoder *thiz, VideoInExtraInfo *extraInfo);
	
	/// 开始编码，由应用向编码模块推数据编码，不调用putPacket接口情况下，由底层编码模块自行决定是否编码
	///
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] packet 视频编码源数据包指针
	/// \return 0 成功
	/// \retval < 0 失败
	int (*putPacket)(struct VideoEncoder *thiz, VideoEncSourcePacket *packet);
	
	/// 设置编码抓拍帧标记，双快门全帧率模式下，允许抓拍帧图像不编入视频，此接口对视频码流有效
	///
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] flag 编码抓拍帧标记，0:不编码，1:编码，默认不编入视频
	/// \retval 0 设置成功
	/// \retval <0设置失败
	int(*setEncodeSnapshot)(struct VideoEncoder *thiz, int flag);

	/// 设置局部编码信息
	///
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] count 视频编码局部个数
	/// \param [in] parts 视频编码局部信息
	/// \retval 0 设置成功
	/// \retval <0设置失败
	int (*setEncodePart)(struct VideoEncoder *thiz, int count, VideoEncPart *parts);
	
	/// 设置抓图模式，此接口对抓图码流有效
	///
	/// \param [in] thiz 抓图编码接口指针
	/// \param [in] modeMask模式掩码			   
	/// \retval 0  设置成功
	/// \retval <0	设置失败
	int (*setSnapShotMode)(struct VideoEncoder *thiz, SnapShotMode modeMask);
	/// 使用 DMA 复制编码数据,若函数指针为空表示不支持DMA拷贝。
	///
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] dst 目标内存地址
	/// \param [in] src 源数据内存地址，这个是从 getPacket 中取得的地址
	/// \param [in] len 源数据长度
	/// \retval 0  成功
	/// \retval <0	失败
	int (*dmaCopy)(struct VideoEncoder *thiz, void* dst, void* src, unsigned int len);

	/// 设置编码区域，允许将采集视野的一部分区域用来编码
	///
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] region 视频编码区域，该区域是视频采集区域的一部分，采用绝对坐标
	/// \retval 0  成功
	/// \retval <0	失败
	int (*setEncRegion)(struct VideoEncoder* thiz, Rect* region);

	/// 根据编码属性计算需要的前端输入属性
	///
	/// \param [in] thiz 视频编码接口指针
	/// \param [in] encOptions 需要配置的编码属性
	/// \param [out] vinOptions 需要配置的前端输入属性
	/// \retval 0  成功
	/// \retval <0	失败
	int (*calcVideoInOptions)(struct VideoEncoder* thiz, VideoEncOptions* encOptions, VideoEncVinOptions* vinOptions);

	/// 查询是否有效数据包
	/// 
	/// \param [in] thiz 视频编码接口指针
	/// \return>0 有效数据包长度
	/// \retval 0 无有效数据包
	/// \retval <0	获取数据包失败
	int (*requestPacket)(struct VideoEncoder *thiz);

	int (*setEncodeCrop)(struct VideoEncoder *thiz, VideoEncCropCfg* cropCfg);

	int (*drawRect)(struct VideoEncoder *thiz, VideoObjectPacket* objPacket);

	int (*getEncodeCrop)(struct VideoEncoder *thiz, VideoEncCropCfg* cropCfg);

	int (*setEncodeStitch)(struct VideoEncoder *thiz, VideoEncStitchCfg* stitchCfg);

	int (*setScreenMode)(struct VideoEncoder *thiz, int mode);

	int (*setDynamicFps)(struct VideoEncoder *thiz, uint8 fps);

	int (*setDynamicBitRate)(struct VideoEncoder *thiz, uint32 uBitRate);

	int (*setDynamicResolution)(struct VideoEncoder *thiz, int u32Width, int u32Height);

	///< 保留字节
	int	*				reserved[92];
} VideoEncoder;


/// 码流类型
typedef enum VideoEncStream
{
	videoEncStreamMain = 0,	///< 主码流
	videoEncStreamExtra1,	///< 辅码流1
	videoEncStreamExtra2,	///< 辅码流2
	videoEncStreamExtra3,	///< 辅码流3
	videoEncStreamSnapshot,	///< 抓图
	videoEncStreamNumber	///< 种类数
} VideoEncStream;


///分辨率枚举值
typedef enum
{
	videoResolution_INVALID,	///< 无效分辨率
	videoResolution_D1,			///< 704*576(PAL)	704*480(NTSC)
	videoResolution_HD1,		///< 352*576(PAL)	352*480(NTSC)
	videoResolution_BCIF,		///< 704*288(PAL)	704*240(NTSC)
	videoResolution_CIF,		///< 352*288(PAL)	352*240(NTSC)
	videoResolution_QCIF,		///< 176*144(PAL)	176*120(NTSC)
	videoResolution_VGA,		///< 640*480
	videoResolution_QVGA,		///< 320*240
	videoResolution_SVCD,		///< 480*480
	videoResolution_QQVGA,		///< 160*128
	videoResolution_SVGA,		///< 800*592
	videoResolution_XVGA,		///< 1024*768
	videoResolution_WXGA,		///< 1280*800
	videoResolution_SXGA,		///< 1280*1024 
	videoResolution_WSXGA,		///< 1600*1024 
	videoResolution_UXGA,		///< 1600*1200
	videoResolution_WUXGA,		///< 1920*1200
	videoResolution_ND1,		///< 240*192
	videoResolution_720P,		///< 1280*720
	videoResolution_1080P,		///< 1920*1080
	videoResolution_1_3M,		///< 1280*960(1.3M)
	videoResolution_2_5M,		///< 1872*1408(2.5M)
	videoResolution_5M,			///< 3744*1408(5M)
	videoResolution_3M,			///< 2048*1536(3M)
	videoResolution_2432_2048, 	///< 2432*2048(5M)
	videoResolution_1216_1024, 	///< 1216*1024(1.2M)
	videoResolution_1408_1024, 	///< 1408*1024(1.5M)
	videoResolution_3296_2472,	///< 3296*2472(8M)
	videoResolution_2560_1920, 	///< 2560*1920(5M)
	videoResolution_960H,		///< 960*576(PAL) 960*480(NTSC)
	videoResolution_960_720,	///< 960*720(DV720P)
	videoResolution_2560_1600,	///< 2560*1600(4M)
	videoResolution_2336_1752, 	///< 2336*1752(4_0M)
	videoResolution_2592_2048, 	///< 2592*2048
	videoResolution_1920_1440, 	///< 1920*1440
	videoResolution_2560_1440, 	///< 2560*1440(4M_16:9)
	videoResolution_2592_1520, 	///< 2592*1520(4M_4:3)
	videoResolution_2304_1296, 	///< 2304*1296(3M_16:9)
	videoResolution_2048_1520, 	///< 2048*1520(3M_4:3)
	videoResolution_4096_2160, 	///< 4096*2160(8M)
	videoResolution_3840_2160, 	///< 3840*2160(8M_16:9)
	videoResolution_2592_1944,	///< 2592*1944(5M)
	videoResolution_4000_3000,	///< 4000*3000(12M_4:3)
	videoResolution_1792_980,	///< 1792*980(1.8M_fisheye)
	videoResolution_1792_1080,  ///< 1792*1080(1.9M_fisheye)
	videoResolution_640_360,    ///< 640*360(nHD)
} VideoResolution; 


/// 各路码流支持的分辨率列表 
typedef struct
{
	VideoResolution	encodeResolutions[videoEncStreamNumber][8]; 	///< 分辨率列表以videoResolution_INVALID值结尾 
	VideoResolution	rotateResolutionLimit[8];						///< 支持旋转90度的分辨率
	float defaultFps[videoEncStreamNumber];							///< 各路码流的默认帧率
} VideoEncoderFormat;


///获取各路径路流支持的分辨率，该接口需要在配置sensor制式和分辨率后配置
///
/// \param [out] encoderFormat 各路码流支持的分辨率列表
/// \retval 0  成功
/// \retval < 0  失败
int PAL_API getEncoderFormat(VideoEncoderFormat *encoderFormat);


///获取各路径路流支持的分辨率，该接口需要在配置sensor制式和分辨率后配置
///
/// \param [out] encoderFormat 各路码流支持的分辨率列表
/// \param [in] viChn 通道号
/// \retval 0  成功
/// \retval < 0  失败
int PAL_API getEncoderFormatEx(VideoEncoderFormat *encoderFormat, int viChn);


/// 视频编码接口描述，128字节
typedef struct VideoEncDesc
{
	VideoEncStream	stream;		///< 指定编码码流的类型
	ulong srcs;					///< 视屏输入通道号掩码，每一位对应一个视频输入物理通道
	int card;					///< 子卡槽位号，0表示主板，>0表示子卡
	int	channel;		        ///< 视频编码通道号
	int reserved[28];			///< 保留
} VideoEncDesc;


/// 创建视频编码设备，编码的对象可能由多个视频输入源组合而成。创建成功后，如果芯片资源
/// 限制，不一定可以正常编码，应用程序需要根据编码能力来计算。
///
/// \param [in] desc  视频编码接口描述结构VideoEncDesc指针
/// \param [out] videoEncoder 视频编码接口指针的指针
/// \retval <0 创建失败
/// \retval 0 创建成功
int PAL_API createVideoEncoder(VideoEncDesc *desc, VideoEncoder **videoEncoder);

void PAL_API destoryVideoEncoder(int streamId);

#ifdef __cplusplus
}
#endif

#endif //__VIDEO_ENC_API_H__

